package com.wstuo.common.rules.entity;

import com.wstuo.common.entity.BaseEntity;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

/**
 * bean of pattern
 * 
 * @author <a href="mailto:376890523@qq.com">jeff</a>
 * @version 0.1 2010.9.28
 */
@SuppressWarnings({ "serial", "rawtypes" })
@Entity
public class RulePattern extends BaseEntity {
	/**
	 * pattern no
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long rulePatternNo;

	/**
	 * pattern type
	 */
	private String patternType;

	/**
	 * pattern binding
	 */
	private String patternBinding;

	/**
	 * sequence
	 */
	private Integer sequence = 0;

	/**
	 * rule
	 */
	@OneToOne(mappedBy = "condition")
	private Rule rule;

	/**
	 * list of constraint
	 */
	@OneToMany(cascade = CascadeType.ALL)
	@JoinColumn(name = "rulePatternNo")
	private List<RuleConstraint> constraints = new ArrayList<RuleConstraint>();

	public Rule getRule() {
		return rule;
	}

	public void setRule(Rule rule) {
		this.rule = rule;
	}

	public List<RuleConstraint> getConstraints() {
		return constraints;
	}

	public void setConstraints(List<RuleConstraint> constraints) {
		this.constraints = constraints;
	}

	public Long getRulePatternNo() {
		return rulePatternNo;
	}

	public void setRulePatternNo(Long rulePatternNo) {
		this.rulePatternNo = rulePatternNo;
	}

	public String getPatternType() {
		return patternType;
	}

	public void setPatternType(String patternType) {
		this.patternType = patternType;
	}

	public String getPatternBinding() {
		return patternBinding;
	}

	public void setPatternBinding(String patternBinding) {
		this.patternBinding = patternBinding;
	}

	public Integer getSequence() {
		return sequence;
	}

	public void setSequence(Integer sequence) {
		this.sequence = sequence;
	}

	/**
	 * toString Method
	 */
	public String toString() {
		StringBuffer buffer = new StringBuffer();

		buffer.append(patternBinding);
		buffer.append(":");
		buffer.append(patternType);
		buffer.append("(");

		for (int i = 0; i < constraints.size(); i++) {
			RuleConstraint c = constraints.get(i);

			if (c.getPropertyType() == true) {
				buffer.append(c.getPropertyName());
				buffer.append("==\"");
				buffer.append(c.getPropertyValue());
				buffer.append("\"");
			} else {
				buffer.append(c.getPropertyName());
				buffer.append("==");
				buffer.append(c.getPropertyValue());
			}

			if (c.getSequence() < constraints.size()) {
				buffer.append(c.getAndOr());
			}
		}

		buffer.append(")");

		return buffer.toString();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((constraints == null) ? 0 : constraints.hashCode());
		result = prime * result
				+ ((patternBinding == null) ? 0 : patternBinding.hashCode());
		result = prime * result
				+ ((patternType == null) ? 0 : patternType.hashCode());
		result = prime * result + ((rule == null) ? 0 : rule.hashCode());
		result = prime * result
				+ ((rulePatternNo == null) ? 0 : rulePatternNo.hashCode());
		result = prime * result
				+ ((sequence == null) ? 0 : sequence.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		RulePattern other = (RulePattern) obj;
		if (constraints == null) {
			if (other.constraints != null)
				return false;
		} else if (!constraints.equals(other.constraints))
			return false;
		if (patternBinding == null) {
			if (other.patternBinding != null)
				return false;
		} else if (!patternBinding.equals(other.patternBinding))
			return false;
		if (patternType == null) {
			if (other.patternType != null)
				return false;
		} else if (!patternType.equals(other.patternType))
			return false;
		if (rule == null) {
			if (other.rule != null)
				return false;
		} else if (!rule.equals(other.rule))
			return false;
		if (rulePatternNo == null) {
			if (other.rulePatternNo != null)
				return false;
		} else if (!rulePatternNo.equals(other.rulePatternNo))
			return false;
		if (sequence == null) {
			if (other.sequence != null)
				return false;
		} else if (!sequence.equals(other.sequence))
			return false;
		return true;
	}
}
